package com.swl.juc.Executor;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.util.concurrent.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class CountDownLatchExecutorTest {

    private static Logger logger = LogManager.getLogger(CountDownLatchExecutorTest.class);
    private static int sum = 0;
    private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();

    public void doSome(int num) {
        //启用线程池(最大不能超过500个)
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                //核心池大小
                50,
                //最大池大小
                5000,
                //线程最大空闲时间,超过此空闲时间可以被收回
                200,
                //最大空闲时间的单位
                TimeUnit.MILLISECONDS,
                //用于保存执行任务的队列,可以选择其他不同的队列来做任务管理
                new LinkedBlockingDeque<>(10)
        );

        CountDownLatch n = new CountDownLatch(5);

        for (int i = 0; i < 10000; i++) {
            //启动一个任务
            Task myTask = new Task(i, n);
            executor.execute(myTask);
        }

        logger.info("全部执行的任务数量:" + executor.getTaskCount());
        logger.info("已完成的任务数量:" + executor.getCompletedTaskCount());
        logger.info("曾经创建过最大的线程数量:" + executor.getPoolSize());
        logger.info("活动的线程数量:" + executor.getPoolSize());

        //等待所有线程完毕
        try {
            n.await();
        } catch (InterruptedException e) {
            logger.error(e);
        }
        System.out.println("所有员工已经到达公司大门口，大巴车发动，前往活动目的地。");
        //关闭线程池
        executor.shutdown();

    }

    class Task implements Runnable {

        private int taskNum;
        CountDownLatch n;

        public Task(int num, CountDownLatch n) {
            this.taskNum = num;
            this.n = n;
        }

        @Override
        public void run() {
            try {
                writeLock.lock();
                //TODO 做你的事情,擦桌子
                sum++;
            } catch (Exception e) {
                logger.error(e);
                logger.info("task " + taskNum + "执行失败");
            } finally {
                writeLock.unlock();
            }
            //事情干完了
            n.countDown();
        }
    }

    public static void main(String[] args) {
        CountDownLatchExecutorTest countDownLatchExecutorTest = new CountDownLatchExecutorTest();
        countDownLatchExecutorTest.doSome(1000);
        System.out.println(sum);
    }
}